'''
Created on Nov 23, 2010

@author: dexen
'''

import time

from dexen.system.common.meta import JobMeta
from dexen.system.common.base import BaseMasterTask
from dexen.system.common.transact import MasterRecvTransact
import traceback
import sys
from dexen.system.node.master.env import MasterEnv


class MasterTaskExecutor(object):
    def __init__(self, job_meta, master_env):
        self.job_meta = job_meta
        self.master_env = master_env
        self.trans_id = 1 # Refers to the master Transactions id
    
    def setup(self):
        job_meta = self.job_meta
        assert isinstance(job_meta, JobMeta)
        job_meta.setup_schema()
        job_meta.setup_env()
        self.master_task = job_meta.get_master_task(self.master_env)
        job_meta.reset_env()
        
    def execute(self):
        job_meta = self.job_meta
        assert isinstance(job_meta, JobMeta)
        master_env = self.master_env
        assert isinstance(master_env, MasterEnv)
        
        job_meta.setup_env()
        master_task = self.master_task
        assert isinstance(master_task, BaseMasterTask)
        try:
            s_time = time.time()
            transact = None
            master_task.__execute__(master_env)
            if master_env._has_state_changed():
                transact = MasterRecvTransact(self.trans_id)
                self.trans_id += 1
                transact.set_exec_time(time.time() - s_time)
                transact.set_inds(master_env._get_updated_inds())
                transact.set_archive(master_env._get_archive())
                transact.task_succeeded()
                master_env._reset()
        except:
            transact = MasterRecvTransact(self.trans_id)
            self.trans_id += 1
            traceback.print_tb(sys.exc_info()[2])
            print sys.exc_info()
            transact.set_err_msg("Error")
            transact.task_failed()
        finally:
            job_meta.reset_env()
            return transact

